/*
 * 描          述:  <描述>
 * 修  改   人:  Administrator
 * 修改时间:  2019年6月8日
 * <修改描述:>
 */
package com.tx.core.mybatis.dao;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.tx.core.mybatis.config.MybatisGlobalConfig;
import com.tx.core.paged.model.PagedList;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

/**
 * 持久层接口<br/>
 * <功能详细描述>
 *
 * @author Administrator
 * @version [版本号, 2019年6月8日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public interface MybatisBaseDao<T, ID extends Serializable> {

    /**
     * 保存或更新对象实例。
     * 如果数据库中已存在该对象的实例，则进行更新；
     * 如果不存在，则插入新的对象实例。
     * 该方法会根据Jpa的注解或MybatisPlus的注解来判断字段是否可更新，
     * 因此更新操作需要传入包含更新逻辑的Map。
     *
     * @param entity 要保存或更新的对象实例。
     */
    void save(T entity);

    /**
     * 保存或更新对象实例。
     * 如果对象已存在（根据主键判断），则进行更新；
     * 如果不存在，则插入新对象。
     * 在更新操作时，需要通过updateWrapperGenerator生成更新条件，系统会根据Jpa或MybatisPlus的注解判断字段是否可更新。
     * 在插入前，如果提供了preInsertFun，将会执行该Consumer函数对对象进行预处理。
     *
     * @param entity        要保存或更新的对象实例。
     * @param updateWrapper 一个函数，用于根据对象实例生成更新条件的Wrapper。
     */
    void save(T entity, Wrapper<T> updateWrapper);

    /**
     * 保存或更新对象实例。
     * 如果对象已存在（根据主键判断），则进行更新；
     * 如果不存在，则插入新对象。
     * 在更新操作时，需要通过updateWrapperGenerator生成更新条件，系统会根据Jpa或MybatisPlus的注解判断字段是否可更新。
     * 在插入前，如果提供了preInsertFun，将会执行该Consumer函数对对象进行预处理。
     *
     * @param entity                 要保存或更新的对象实例。
     * @param updateWrapperGenerator 一个函数，用于根据对象实例生成更新条件的Wrapper。
     */
    void save(T entity, Function<T, Wrapper<T>> updateWrapperGenerator);

    /**
     * 批量保存对象实例
     * <br/>
     * 如果数据库中已存在对应的记录，则进行更新；
     * 如果不存在，则插入新的记录。
     * <p>
     * 由于更新逻辑需要传入Map，会根据Jpa的注解或MybatisPlus的注解判断字段是否可更新。
     * </p>
     *
     * @param entityList 要进行批量保存的对象实例列表
     */
    default void batchSave(List<T> entityList) {
        batchSave(entityList, MybatisGlobalConfig.DEFAULT_DO_FLUSH_SIZE, false);
    }

    /**
     * 批量保存对象实例<br/>
     * 如果存在则更新，如果不存在则插入。该方法会根据实体列表中的对象批量进行数据库操作。
     * 由于更新逻辑需要传入Map，所以会根据Jpa的注解或MybatisPlus的注解判断字段是否可更新。
     *
     * @param entityList       实体列表，需要保存或更新的对象集合。
     * @param useBatchExecutor 是否利用batchExecutor进行执行。如果为true，则使用批处理执行器进行批量操作，提高效率。
     */
    default void batchSave(List<T> entityList, boolean useBatchExecutor) {
        batchSave(entityList, MybatisGlobalConfig.DEFAULT_DO_FLUSH_SIZE, useBatchExecutor);
    }

    /**
     * 批量保存对象实例
     * <p>该方法会遍历传入的实体列表，对于每个实体，如果数据库中已存在，则进行更新；如果不存在，则进行插入。</p>
     * <p>由于更新逻辑需要传入Map形式的数据，因此在更新操作时，会根据Jpa的注解或MybatisPlus的注解来判断字段是否可更新。</p>
     *
     * @param entityList       实体列表，包含需要进行批量保存的对象实例。
     * @param doFlushSize      每执行到一定数量的保存操作后，是否进行一次flush。用于控制批量操作的分批执行策略。
     * @param useBatchExecutor 是否利用batchExecutor进行执行。如果为true，则使用批处理执行器进行批量操作，提高效率。
     */
    void batchSave(List<T> entityList, int doFlushSize, boolean useBatchExecutor);

    /**
     * 批量保存实体列表。
     * 该方法会遍历实体列表，对于每个实体，首先应用updateWrapperFun函数生成更新条件，尝试进行更新操作；
     * 如果更新操作未影响到任何行（即该实体不存在于数据库中），则调用preInsertFun函数进行预处理后，
     * 插入该实体到数据库中。
     *
     * @param entityList             实体列表，包含了需要进行批量保存的实体。
     * @param updateWrapperGenerator 一个函数，接收一个实体作为参数，返回一个Wrapper对象，用于构造更新条件。
     */
    default void batchSave(List<T> entityList, Function<T, Wrapper<T>> updateWrapperGenerator) {
        batchSave(entityList, updateWrapperGenerator, MybatisGlobalConfig.DEFAULT_DO_FLUSH_SIZE, false);
    }

    /**
     * 批量保存实体列表，提供了对执行器类型的控制。
     * 该方法允许通过控制是否使用batchExecutor来调整批量操作的执行策略。对于每个实体，首先尝试根据更新条件进行更新，
     * 如果该实体不存在于数据库中，则进行预处理后插入。
     *
     * @param entityList             实体列表，包含了需要进行批量保存的实体。
     * @param updateWrapperGenerator 一个函数，接收一个实体作为参数，返回一个Wrapper对象，用于构造更新条件。
     * @param useBatchExecutor       一个布尔值，指示是否使用batchExecutor执行批量操作。true表示使用batchExecutor，false表示不使用。
     */
    default void batchSave(List<T> entityList, Function<T, Wrapper<T>> updateWrapperGenerator,
                           boolean useBatchExecutor) {
        batchSave(entityList, updateWrapperGenerator, MybatisGlobalConfig.DEFAULT_DO_FLUSH_SIZE,
                useBatchExecutor);
    }

    /**
     * 批量保存实体列表。
     * 该方法允许对实体列表进行批量保存操作。首先尝试根据更新条件更新实体，如果实体不存在，则进行预处理后插入。
     * 可以通过参数控制批量操作的执行策略，包括刷新大小和是否使用批量执行器。
     *
     * @param entityList             实体列表，包含需要保存的实体。
     * @param updateWrapperGenerator 一个函数，接收一个实体作为参数，返回一个Wrapper对象，用于构造更新条件。
     * @param doFlushSize            刷新大小，即在执行批量保存操作前，收集多少条数据后进行一次刷新。
     * @param useBatchExecutor       一个布尔值，指示是否使用batchExecutor执行批量操作。true表示使用batchExecutor，false表示不使用。
     */
    void batchSave(List<T> entityList, Function<T, Wrapper<T>> updateWrapperGenerator,
                   int doFlushSize, boolean useBatchExecutor);

    /**
     * 插入一个对象实例到数据库中。<br/>
     * 该方法会将提供的实体对象插入到对应的数据库表中，如果该对象不存在于数据库中的话。
     *
     * @param entity 需要被插入的对象实例。该参数不能为空。
     */
    void insert(T entity);

    /**
     * 批量插入对象实例
     * <br/>
     * 该方法会将提供的实体列表批量插入到数据库中。这是通过调用 {@code batchInsert(List<T> entityList, int flushSize, boolean autoFlush)} 方法实现的，
     * 使用的是默认的刷新大小（{@code MybatisGlobalConfig.DEFAULT_DO_FLUSH_SIZE}）和自动刷新标志（{@code false}）。
     *
     * @param entityList 要插入的实体对象列表，不应为 {@code null}。
     */
    default void batchInsert(List<T> entityList) {
        batchInsert(entityList, MybatisGlobalConfig.DEFAULT_DO_FLUSH_SIZE, false);
    }

    /**
     * 批量插入对象实例
     * <br/>
     * 该方法通过批量执行的方式插入对象实例列表到数据库。可以选择是否使用批量执行器来优化插入性能。
     *
     * @param entityList       要插入的对象实例列表，不应为空。
     * @param useBatchExecutor 指定是否使用批量执行器来执行插入操作。当设置为true时，将使用批量执行器，可能会提高插入性能。
     */
    default void batchInsert(List<T> entityList, boolean useBatchExecutor) {
        batchInsert(entityList, MybatisGlobalConfig.DEFAULT_DO_FLUSH_SIZE, useBatchExecutor);
    }

    /**
     * 批量插入对象实例
     * <br/>
     * 该方法用于将一批实体对象插入到数据库中。支持通过配置是否使用批量执行器来优化插入性能。
     *
     * @param entityList       要插入的实体对象列表，列表中的对象类型应为泛型 T 的实例。
     * @param doFlushSize      执行刷新的大小，即当插入实体的数量达到该值时，会自动执行刷新操作。
     * @param useBatchExecutor 是否使用批量执行器。当设置为 true 时，将使用批量执行策略来插入实体，以提高效率。
     */
    void batchInsert(List<T> entityList, int doFlushSize, boolean useBatchExecutor);

    /**
     * 删除对象实例
     * 该方法根据主键删除数据库中的一个对象实例。如果删除成功，则返回true；否则返回false。
     *
     * @param pk 主键，用于标识要删除的对象实例
     * @return boolean 返回删除操作的结果，成功为true，失败为false
     */
    boolean delete(ID pk);

    /**
     * 删除对象实例
     * 该方法用于根据提供的对象实例删除相应的数据库记录。
     *
     * @param entity 需要删除的对象实例。该参数是泛型T的实例，代表任意类型的数据实体。
     * @return 返回删除操作影响的记录数。通常，如果删除成功，返回值为1；如果失败或无影响，则返回其他值。
     * @return int 返回删除操作的影响行数。
     */
    int delete(T entity);

    /**
     * 批量删除对象实例
     * 该方法提供了一种批量删除数据库记录的机制，通过传入一个对象实例的列表来执行删除操作。<br/>
     * 注意：此操作可能会导致数据库中大量数据被删除，请谨慎使用。
     *
     * @param entityList 需要删除的对象实例列表。该参数是一个泛型List<T>，代表任意类型的数据实体的集合。
     */
    default void batchDelete(List<T> entityList) {
        batchDelete(entityList, MybatisGlobalConfig.DEFAULT_DO_FLUSH_SIZE, false);
    }

    /**
     * 批量删除对象实例<br/>
     * 该方法通过传入的对象列表批量删除相应的数据库记录。可以选择是否使用批量执行器来优化删除操作的性能。<br/>
     *
     * @param entityList       要删除的对象实例列表，类型为泛型T的List。
     * @param useBatchExecutor 是否使用批量执行器来执行删除操作。如果为true，则使用批量执行器；如果为false，则不使用。
     */
    default void batchDelete(List<T> entityList, boolean useBatchExecutor) {
        batchDelete(entityList, MybatisGlobalConfig.DEFAULT_DO_FLUSH_SIZE, useBatchExecutor);
    }

    /**
     * 批量删除对象实例<br/>
     * 该方法通过传入的对象列表批量删除相应的数据库记录。可以通过参数控制是否使用批量执行器以及批量执行的大小。<br/>
     *
     * @param entityList       要删除的对象实例列表，类型为泛型T的List。
     * @param doFlushSize      执行批量操作时的刷新大小，即每次提交到数据库的记录数。
     * @param useBatchExecutor 是否使用批量执行器来执行删除操作。如果为true，则使用批量执行器；如果为false，则不使用。
     */
    void batchDelete(List<T> entityList, int doFlushSize, boolean useBatchExecutor);

    /**
     * 更新对象实例
     * <br/>
     * 该方法通过接收一个包含更新信息的Map对象，来更新特定的对象实例。Map中的键值对代表了需要更新的属性名和对应的值。
     *
     * @param updateEntityMap 包含更新信息的Map对象，其中键是属性名，值是需要更新的值。
     * @return 返回更新操作影响的行数。
     */
    int update(Map<String, Object> updateEntityMap);

    /**
     * 根据主键修改对象实例
     * <br/>
     * 该方法通过主键标识特定的对象实例，并根据提供的Map对象来更新该实例的属性值。Map中的键代表属性名，值代表需要更新的属性值。
     *
     * @param pk              主键，用于标识唯一对象实例
     * @param updateEntityMap 包含更新信息的Map对象，其中键是属性名，值是需要更新的值。
     * @return 返回一个布尔值，表示更新操作是否成功。
     */
    boolean update(ID pk, Map<String, Object> updateEntityMap);

    /**
     * 更新对象实例<br/>
     * 本方法是一个默认方法，提供了一个简化的更新过程，通过一个Wrapper包装器和一个可选的参数进行更新。<br/>
     *
     * @param wrapper 用于封装更新信息的Wrapper对象，其中包含了要更新的对象实例和相关的更新逻辑。
     * @return 返回更新操作的结果，通常是一个整数，如更新影响的行数。
     */
    int update(Wrapper<T> wrapper);

    /**
     * 根据主键以及wrapper更新对象实例的默认实现。
     * 这个方法会调用另一个重载的update方法，传递null作为第三个参数。
     *
     * @param pk      主键，用于标识要更新的对象实例。
     * @param wrapper 包装器，包含了更新操作的条件和数据。
     * @return 返回一个布尔值，表示更新操作是否成功。
     */
    boolean update(ID pk, Wrapper<T> wrapper);

    /**
     * 更新指定的实体对象。
     *
     * @param entity 需要更新的实体对象，类型为泛型 T。
     * @return 更新操作影响的行数。
     */
    int update(T entity);

    /**
     * 根据主键更新实体对象<br/>
     * 本方法用于根据给定的主键标识来更新对应的实体对象。如果实体存在，则更新其状态；如果不存在，则不进行任何操作。<br/>
     *
     * @param pk     主键，用于标识需要更新的实体。它是实体唯一标识的一部分。
     * @param entity 需要更新的实体对象实例。包含了实体的属性及其更新后的值。
     * @return 返回一个布尔值，表示更新操作是否成功。成功返回true，失败返回false。
     */
    boolean update(ID pk, T entity);

    /**
     * 更新指定的实体对象。
     *
     * @param entity 需要更新的实体对象，类型为泛型 T。
     * @return 更新操作影响的行数。
     */
    int update(T entity, Function<T, Wrapper<T>> updateWrapperGenerator);

    /**
     * 根据主键更新实体对象<br/>
     * 本方法用于根据给定的主键标识来更新对应的实体对象。如果实体存在，则更新其状态；如果不存在，则不进行任何操作。<br/>
     *
     * @param pk     主键，用于标识需要更新的实体。它是实体唯一标识的一部分。
     * @param entity 需要更新的实体对象实例。包含了实体的属性及其更新后的值。
     * @return 返回一个布尔值，表示更新操作是否成功。成功返回true，失败返回false。
     */
    boolean update(ID pk, T entity, Function<T, Wrapper<T>> updateWrapperGenerator);

    /**
     * 批量更新对象实例<br/>
     * 本方法是一个默认方法，提供了一个简化的批量更新过程，通过一个实体列表进行更新。<br/>
     *
     * @param entityList 包含需要更新的对象实例的列表。
     */
    default void batchUpdate(List<T> entityList) {
        batchUpdate(entityList, MybatisGlobalConfig.DEFAULT_DO_FLUSH_SIZE, false);
    }

    /**
     * 批量更新对象实例<br/>
     * 本方法是一个默认方法，提供了一个简化的批量更新过程，通过一个实体列表进行更新。<br/>
     *
     * @param entityList 包含需要更新的对象实例的列表。
     */
    default void batchUpdate(List<T> entityList, boolean useBatchExecutor) {
        batchUpdate(entityList, MybatisGlobalConfig.DEFAULT_DO_FLUSH_SIZE, useBatchExecutor);
    }

    /**
     * 批量更新对象实例<br/>
     * 本方法是一个默认方法，提供了一个简化的批量更新过程，通过一个实体列表进行更新。<br/>
     *
     * @param entityList 包含需要更新的对象实例的列表。
     */
    void batchUpdate(List<T> entityList, int doFlushSize, boolean useBatchExecutor);

    /**
     * 批量更新对象实例<br/>
     * 此方法通过提供的实体列表和更新包装器生成器，来批量更新数据库中的记录。更新操作将会根据每个实体的具体情况，由更新包装器生成器动态生成更新条件和更新内容。
     *
     * @param entityList       需要进行批量更新的实体列表，不应为空。
     * @param wrapperGenerator 一个函数接口，用于根据实体实例动态生成更新操作的包装器。该函数接收一个实体实例，返回一个对应该实体的更新包装器。
     */
    default void batchUpdate(List<T> entityList, Function<T, Wrapper<T>> wrapperGenerator) {
        batchUpdate(entityList, wrapperGenerator, MybatisGlobalConfig.DEFAULT_DO_FLUSH_SIZE, false);
    }

    /**
     * 批量更新对象实例<br/>
     * 该方法允许通过提供的实体列表和更新包装器生成器来批量更新数据库中的记录。更新操作的执行方式可以根据需要选择使用批量执行器。
     *
     * @param entityList       需要进行批量更新的实体列表，不应为空。
     * @param wrapperGenerator 一个函数接口，用于根据实体实例动态生成更新操作的包装器。该函数接收一个实体实例，返回一个对应该实体的更新包装器。
     * @param useBatchExecutor 一个布尔值，指示是否使用批量执行器来执行更新操作。当设置为true时，将使用批量执行器，从而可能提高更新效率。
     */
    default void batchUpdate(List<T> entityList, Function<T, Wrapper<T>> wrapperGenerator,
                             boolean useBatchExecutor) {
        batchUpdate(entityList, wrapperGenerator, MybatisGlobalConfig.DEFAULT_DO_FLUSH_SIZE, useBatchExecutor);
    }

    /**
     * 批量更新对象实例<br/>
     * 该方法用于根据提供的实体列表，通过生成更新包装器，批量更新这些实体。可以配置是否使用批量执行器以及刷新的大小来优化更新过程。
     *
     * @param entityList       需要更新的实体列表，类型为泛型T。
     * @param wrapperGenerator 一个函数接口，用于根据实体实例生成对应的更新条件包装器。接收一个实体对象，返回一个针对该实体的更新条件包装器。
     * @param doFlushSize      执行刷新的大小，即当更新操作累积到一定数量时，会执行一次数据库刷新操作。
     * @param useBatchExecutor 是否使用批量执行器来执行更新操作。如果为true，则使用批量执行策略，可以提高更新效率。
     */
    void batchUpdate(List<T> entityList, Function<T, Wrapper<T>> wrapperGenerator, int doFlushSize,
                     boolean useBatchExecutor);

    /**
     * 根据主键查询对象实例<br/>
     * 本方法通过指定的主键值来查找对应的对象实例。如果找到，则返回该对象实例；如果没有找到，则返回null。<br/>
     *
     * @param pk 主键值，用于查找对象实例的唯一标识。
     * @return 返回查询到的对象实例，如果没有找到则返回null。
     */
    T find(ID pk);

    /**
     * 根据对象实例查询数据库中对应的记录<br/>
     * 本方法通过传入一个对象实例，根据该实例的属性值去数据库中查询与之匹配的记录，并返回查询结果。<br/>
     *
     * @param entity 用于查询的实体对象，其属性将被用于生成查询条件。
     * @return 返回查询到的对象实例，如果没有找到匹配的记录，则返回null。
     */
    T find(T entity);

    /**
     * 根据条件查询对象实例列表<br/>
     * 该方法接收一个参数映射，利用其中的条件来查询特定的对象实例列表。<br/>
     *
     * @param params 一个包含查询条件的键值对映射。键代表查询条件的名称，值代表查询条件的具体值。
     * @return 返回一个满足查询条件的对象实例列表，列表的类型为泛型 T。
     */
    List<T> queryList(Map<String, Object> params);

    /**
     * 根据条件查询对象实例列表，此为默认方法的实现<br/>
     * 调用此方法将根据提供的Wrapper条件进行查询，不需传递额外的参数。<br/>
     * 如果需要传递参数，请使用重载的queryList方法。<br/>
     *
     * @param wrapper 用于设置查询条件的Wrapper对象
     * @return 返回符合条件的对象实例列表，列表类型为泛型T
     */
    default List<T> queryList(Wrapper wrapper) {
        return queryList(wrapper, null);
    }

    /**
     * 根据条件查询对象实例列表<br/>
     * 本方法用于根据提供的条件查询特定对象的实例列表。可以通过Wrapper对象设置复杂的查询条件，同时可以通过Map对象传递动态的参数值，以实现灵活的查询需求。
     *
     * @param wrapper 用于设置查询条件的Wrapper对象
     * @param params  包含查询参数的Map对象
     * @return 返回符合条件的对象实例列表，列表类型为泛型T
     */
    List<T> queryList(Wrapper wrapper, Map<String, Object> params);

    /**
     * 根据条件查询对象实例的分页列表。该方法通过给定的条件参数、页码和每页大小，查询符合条件的对象实例，并返回一个分页列表。
     *
     * @param params    查询条件参数，以键值对的形式提供，用于构建查询条件。
     * @param pageIndex 请求的页码，表示需要返回的页码。
     * @param pageSize  每页的大小，即每页返回的对象实例数量。
     * @return PagedList<T> 返回一个分页列表，其中T代表查询结果对象的类型。
     */
    PagedList<T> queryPagedList(Map<String, Object> params, int pageIndex, int pageSize);

    /**
     * 根据条件查询对象实例的分页列表。此方法提供了一个基础的查询框架，允许根据特定条件（由Wrapper<T>定义）来获取对象实例的分页列表。
     * 该方法重载了另一个queryPagedList方法，允许不指定排序条件直接进行分页查询。
     *
     * @param wrapper   用于查询条件的包装器，定义了查询时的筛选规则。
     * @param pageIndex 请求的页码，表示需要获取第几页的数据。
     * @param pageSize  每页显示的记录数。
     * @return PagedList<T> 返回一个分页列表，包含了查询结果的分页信息和数据。
     */
    default PagedList<T> queryPagedList(Wrapper wrapper, int pageIndex,
                                        int pageSize) {
        return queryPagedList(wrapper, null, pageIndex, pageSize);
    }


    /**
     * 根据条件查询对象实例的分页列表。<br/>
     * 该方法支持通过条件包装器（Wrapper）和额外参数（params）来定制查询，并返回查询结果的分页列表。
     *
     * @param wrapper   用于构建查询条件的Wrapper对象，定义了查询时的筛选、排序等规则。
     * @param params    额外的查询参数，可以用于进一步筛选数据。该参数为可选，不必须。
     * @param pageIndex 请求的页码，表示需要获取第几页的数据。
     * @param pageSize  每页显示的记录数。
     * @return 返回一个PagedList<T>对象，其中包含了查询结果的分页信息（如总页数、当前页码、总记录数等）和数据列表。
     */
    PagedList<T> queryPagedList(Wrapper wrapper, Map<String, Object> params, int pageIndex,
                                int pageSize);

    /**
     * 根据条件查询对象实例的分页列表。<br/>
     * 该方法通过传入的参数Map、页码、每页大小和总记录数来获取特定条件下的对象实例分页列表。
     *
     * @param params    查询条件参数，以键值对的形式传入，用于定制查询条件。
     * @param pageIndex 请求的页码，用于指定要返回的页码。
     * @param pageSize  每页的大小，即每页返回的记录数。
     * @param count     总记录数，用于分页计算。
     * @return 返回一个PagedList<T>对象，包含了查询结果的分页信息和数据列表。
     */
    PagedList<T> queryPagedList(Map<String, Object> params,
                                int pageIndex, int pageSize, int count);

    /**
     * 根据条件查询对象实例的分页列表。此方法提供了一种根据特定条件查询数据集的方式，并将结果以分页形式返回。
     * <p>详细功能描述：</p>
     * <ul>
     *     <li>通过条件包装器（Wrapper）指定查询条件。</li>
     *     <li>允许指定返回结果的页码和每页大小。</li>
     *     <li>方法内部会根据提供的条件执行查询，并返回对应页码的分页列表。</li>
     * </ul>
     *
     * @param wrapper   查询条件，使用Wrapper对象封装查询条件。
     * @param pageIndex 要返回的页码，表示返回第几页的数据。
     * @param pageSize  每页的大小，表示每页返回的数据条数。
     * @param count     查询结果的总条数，此参数通常用于计算总页数，但本方法未直接使用此参数。
     * @return PagedList<T> 返回查询结果的分页列表，列表中的元素类型为泛型T。
     */
    default PagedList<T> queryPagedList(Wrapper wrapper, int pageIndex,
                                        int pageSize, int count) {
        // 调用简化版本的分页查询方法，将页码和每页大小的管理简化处理
        return queryPagedList(wrapper, null, pageIndex, pageSize, count);
    }


    /**
     * 根据条件查询对象实例的分页列表。该方法通过给定的查询条件、页码和每页大小，从数据库中检索数据，并返回对应的结果集。
     *
     * @param wrapper   查询条件包装器，用于构建查询时的条件。
     * @param params    查询参数，以键值对形式提供，用于指定查询时的额外条件。
     * @param pageIndex 请求的页码，表示需要返回的页码。
     * @param pageSize  每页的大小，指定每页返回的结果数量。
     * @param count     总数，表示查询结果的总数，用于计算分页。
     * @return 返回一个PagedList<T>对象，其中包含了查询结果的分页信息和数据列表。
     */
    PagedList<T> queryPagedList(Wrapper wrapper, Map<String, Object> params, int pageIndex,
                                int pageSize, int count);

    /**
     * 根据条件查询对象实例数量<br/>
     * 该方法是count(Map<String, Object> params, ID exclude)方法的简化版本，它不进行排除特定ID的对象计数。
     * <功能详细描述>
     *
     * @param params 用于查询条件的参数映射。键值对形式，具体键值含义依据实际使用场景定义。
     * @return 返回符合条件的对象实例数量。返回类型为int。
     */
    default int count(Map<String, Object> params) {
        // 调用带exclude参数的count方法，将exclude设为null
        return count(params, null);
    }

    /**
     * 根据条件查询对象实例数量
     * 该方法用于根据提供的参数条件查询特定类型对象的实例数量。如果提供了exclude参数，则从计数中排除该对象。
     *
     * @param params  用于查询条件的参数映射。键值对形式，具体键值含义依据实际使用场景定义。
     * @param exclude 需要排除在计数之外的对象ID。如果需要排除特定对象，则将该对象的ID传入此参数。
     * @return 返回符合条件的对象实例数量。返回类型为int。
     */
    int count(Map<String, Object> params, ID exclude);

    /**
     * 根据条件查询对象实例数量<br/>
     * 该方法将根据提供的条件查询特定类型对象的实例数量。<br/>
     *
     * @param wrapper 查询条件的包装器，用于指定查询的条件。
     * @return 返回符合条件的对象实例数量。
     */
    default int count(Wrapper wrapper) {
        // 调用重载的count方法，不进行任何排除条件的设置
        return count(wrapper, null, null);
    }

    /**
     * 根据条件查询对象实例数量，排除特定ID的实例<br/>
     *
     * @param wrapper 查询条件的包装器，用于指定查询的条件。
     * @param exclude 需要排除的对象ID，即在计数时不考虑此ID的对象实例。
     * @return 返回符合条件且不包括指定ID的对象实例数量。
     */
    default int count(Wrapper wrapper, ID exclude) {
        // 调用重载的count方法，排除指定ID的实例
        return count(wrapper, null, exclude);
    }

    /**
     * 根据条件查询对象实例数量<br/>
     * 这是一个默认方法，用于根据条件查询对象实例的数量。它调用了另一个重载的count方法，该方法允许排除特定的ID。
     *
     * @param wrapper 查询条件的包装器，用于指定查询的条件。
     * @param params  一个包含查询可能需要的额外参数的映射。
     * @return 返回符合条件的对象实例数量。
     */
    default int count(Wrapper wrapper, Map<String, Object> params) {
        // 调用重载的count方法，排除ID为null的实例
        return count(wrapper, params, null);
    }

    /**
     * 根据条件查询对象实例数量<br/>
     * 该方法用于根据提供的条件查询特定对象的实例数量。可以排除特定ID的实例。
     *
     * @param wrapper 查询条件，用于构建查询条件的包装器对象。
     * @param params  可选参数映射，可用于进一步定制查询条件。
     * @param exclude 需要排除的ID，即在计数时不考虑该ID对应的实例。
     * @return int 返回符合条件的对象实例数量。
     */
    int count(Wrapper wrapper, Map<String, Object> params, ID exclude);

    /**
     * 判断指定条件的对象实例是否存在
     * <br/>
     * 根据提供的参数映射和可能的额外条件，查询数据库或其他数据源，以确定是否存在满足条件的记录。
     *
     * @param params 包含查询条件的映射对象。键值对形式，其中键代表查询条件的字段名，值代表查询条件的值。
     * @return 返回一个布尔值，如果存在满足条件的记录，则返回true；否则返回false。
     */
    default boolean exist(Map<String, Object> params) {
        // 根据参数计算符合条件的记录数
        int count = count(params, null);
        // 判断记录数是否大于0，以确定对象实例是否存在
        return count > 0;
    }

    /**
     * 判断指定条件的对象实例是否存在<br/>
     * 通过传入的参数条件和排除的ID，检查数据库中是否存在满足条件的记录。
     *
     * @param params  包含查询条件的键值对参数
     * @param exclude 需要排除的ID，即在查询时不考虑此ID对应的记录
     * @return 返回一个布尔值，如果存在满足条件的记录则返回true，否则返回false
     */
    default boolean exist(Map<String, Object> params, ID exclude) {
        // 根据条件查询记录的数量
        int count = count(params, exclude);
        // 判断记录数量是否大于0，大于则表示存在满足条件的记录
        return count > 0;
    }

    /**
     * 判断指定条件的对象实例是否存在
     * <br/>
     * 通过给定的条件包装器（Wrapper）来查询满足条件的对象数量，根据数量判断是否存在满足条件的对象实例。
     *
     * @param wrapper 条件包装器，封装了查询条件，用于筛选特定的对象实例
     * @return boolean 返回true如果存在满足条件的对象实例，否则返回false
     */
    default boolean exist(Wrapper wrapper) {
        // 根据条件查询满足条件的对象数量
        int count = count(wrapper, null, null);
        // 判断查询结果数量是否大于0，大于0表示存在满足条件的对象实例
        return count > 0;
    }

    /**
     * 判断指定条件的对象实例是否存在<br/>
     * 通过给定的条件和排除的ID，检查数据库中是否存在满足条件的记录。
     *
     * @param wrapper 包含查询条件的对象，用于指定查询时的条件
     * @param exclude 需要排除的ID，即在判断存在性时，不考虑此ID对应的记录
     * @return 返回一个布尔值，如果存在满足条件的记录则返回true，否则返回false
     */
    default boolean exist(Wrapper wrapper, ID exclude) {
        // 根据条件和排除的ID计算满足条件的记录数
        int count = count(wrapper, null, exclude);
        // 判断记录数是否大于0，大于0则表示存在满足条件的记录
        return count > 0;
    }

    /**
     * 判断指定条件的对象实例是否存在
     * <br/>
     * 通过给定的条件包装器（Wrapper）和参数映射（Map），查询满足条件的记录数。
     * 如果记录数大于0，则判断为存在满足条件的对象实例。
     *
     * @param wrapper 条件包装器，用于指定查询条件
     * @param params  参数映射，用于传递查询条件所需的参数
     * @return boolean 返回一个布尔值，如果存在满足条件的实例则返回true，否则返回false
     */
    default boolean exist(Wrapper wrapper, Map<String, Object> params) {
        // 根据条件查询记录数
        int count = count(wrapper, params, null);
        // 判断记录数是否大于0，大于则表示存在满足条件的实例
        return count > 0;
    }

    /**
     * 判断指定条件的对象实例是否存在
     * <p>
     * 通过给定的条件包装器（Wrapper）和参数（params）来查询数据库中符合条件的记录数量，
     * 如果排除ID（exclude）被提供，则不计算此ID对应的记录。
     * 根据查询结果的数量判断对象实例是否存在。
     *
     * @param wrapper 条件包装器，用于构建查询条件
     * @param params  包含查询参数的映射，用于动态构建查询条件
     * @param exclude 需要排除的ID，可选参数，用于确保查询结果不包括特定ID的记录
     * @return boolean 返回true如果存在至少一个符合条件的记录，否则返回false
     */
    default boolean exist(Wrapper wrapper, Map<String, Object> params, ID exclude) {
        int count = count(wrapper, params, exclude); // 计算符合条件的记录数量
        // 根据记录数量判断对象实例是否存在
        return count > 0;
    }

    /**
     * 判断指定条件的对象实例是否唯一
     * 本方法通过给定的参数条件来查询数据库中对应记录的数量，以此判断是否存在唯一的记录。
     *
     * @param params 包含查询条件的键值对参数，用于构建查询语句的条件。
     * @return Boolean 如果查询结果唯一，则返回true；如果查询结果为空，则返回null；否则返回false。
     * 通过返回值可以判断指定条件的记录是否唯一或者不存在。
     */
    default Boolean unique(Map<String, Object> params) {
        // 根据参数查询记录的数量
        int count = count(params);
        boolean flag = count == 1; // 判断记录数量是否为1
        // 根据记录数量返回相应的布尔值，判断记录是否唯一或不存在
        return count == 1 ? true : count == 0 ? null : false;
    }

    /**
     * 判断指定条件的对象实例是否唯一
     * 通过给定的Wrapper条件对数据进行查询，判断满足条件的数据在数据库中是否唯一。
     * 如果唯一返回true，如果不存在返回null，否则返回false。
     *
     * @param wrapper 包含查询条件的Wrapper对象，用于指定查询的条件
     * @return Boolean 如果满足条件的数据唯一，则返回true；如果不存在满足条件的数据，则返回null；否则返回false。
     */
    default Boolean unique(Wrapper wrapper) {
        int count = count(wrapper); // 根据wrapper条件查询记录数
        // 根据记录数判断实例是否唯一：记录数为1表示唯一，为0表示不存在，大于1表示不唯一
        return count == 1 ? true : count == 0 ? null : false;
    }

    /**
     * 判断指定条件的对象实例是否唯一<br/>
     * 通过给定的条件（封装在Wrapper中）和参数（Map形式），查询数据库中满足条件的记录数，
     * 从而判断是否存在唯一的记录。<br/>
     * 如果记录数为1，则认为条件下的实例是唯一的；如果记录数为0，表示没有找到符合条件的记录，
     * 对于这种情况，本方法返回null；如果记录数大于1，表示存在多个符合条件的记录，
     * 则认为实例不是唯一的。<br/>
     * <功能详细描述>
     *
     * @param wrapper 用于封装查询条件的对象
     * @param params  包含查询参数的Map
     * @return 如果查询结果唯一则返回true，如果没有找到记录则返回null，否则返回false
     */
    default Boolean unique(Wrapper wrapper, Map<String, Object> params) {
        int count = count(wrapper, params); // 计算满足条件的记录数
        return count == 1 ? true : count == 0 ? null : false; // 根据记录数判断实例是否唯一
    }
}